﻿using System;
using System.Collections.Generic;
using Jayden.Dll.Web.Enums;
using Jayden.Dll.Web.Exceptions;
using Jayden.Dll.Web.HtmlControls.Descriptions;
using Jayden.Dll.Web.HtmlControls.Generics;
using Jayden.Dll.Web.HtmlControls.Interfaces;

namespace Jayden.Dll.Web.HtmlControls
{
	public class OptGroup : HtmlElement, WithLabel, WithDisabled
	{
		public OptGroup() : base(OptGroupDescription.Instance) { }

		public string Label { get { return this["label"]; } set { this["label"] = value; } }
		public bool Disabled { get { return GetAttributeBool("disabled"); } set { SetAttribute("disabled", value); } }
		public bool Enabled { get { return !Disabled; } set { Disabled = !value; } }

		public Option AddOption() { return AddControl(new Option()) as Option; }
		public Option AddOption(string value, string text) { return AddControl(new Option(value, text)) as Option; }
		public Option AddOption(Option option) { return AddControl(option) as Option; }


		public string[] SelectedValues
		{
			get
			{
				List<string> values = new List<string>();
				if(m_ChildControls != null && m_ChildControls.Count > 0)
					foreach(HtmlControl control in m_ChildControls)
					{
						if (control is Option)
						{
							Option option = control as Option;
							if (option.Selected)
							{
								if (option.Value != null)
									values.Add(option.Value);
								else if (option.ChildControls != null && option.ChildControls.Count == 1 && option.ChildControls[0] is HtmlText)
									values.Add((option.ChildControls[0] as HtmlText).Text);
								else
									throw new HtmlException("Invalid <option> with 'checked' attribute but no value.");
							}
						}
					}
				return values.ToArray();
			}
			set
			{
				HashSet<string> values = new HashSet<string>(value);
				if(m_ChildControls != null && m_ChildControls.Count > 0)
					foreach(HtmlControl control in m_ChildControls)
					{
						if (control is Option)
						{
							Option option = control as Option;
							if (option.Value != null)
								option.Selected = values.Contains(option.Value);
							else if (option.ChildControls != null && option.ChildControls.Count == 1 && option.ChildControls[0] is HtmlText)
								option.Selected = values.Contains((option.ChildControls[0] as HtmlText).Text);
							else
								throw new HtmlException("Invalid <option> with 'checked' attribute but no value.");
						}
					}
			}
		}
		public string SelectedValue {
			get
			{
				string[] values = SelectedValues;
				if (values.Length == 1)
					return values[0];
				return null;
			}
			set { SelectedValues = new string[] { value }; }
		}

		protected override void TranslateAttributes(Core.Translations.ITranslator translator)
		{
			base.TranslateAttributes(translator);
			Label = translator.Translate(Label);
		}
	}
	public class OptGroupDescription : HtmlElementDescription
	{
		public static readonly OptGroupDescription Instance = new OptGroupDescription();
		private OptGroupDescription() : base("optgroup", HtmlVersion.Html4, true, true) { }
		public override Type ControlType { get { return typeof(OptGroup); } }
		public override string Description { get { return "group of option elements with a common label."; } }
		public override bool AllowInnerText { get { return false; } }
		public override IEnumerable<HtmlElementDescription> PermittedElements { get { yield return OptionDescription.Instance; } }
		public override IEnumerable<HtmlElementDescription> PermittedParents { get { yield return SelectDescription.Instance; } }
	}
}
